package com.api.test;


import java.io.IOException;
import java.util.Collections;
import java.util.Date;

import com.bin.common.utils.DateTimeUtils;
import com.bin.common.utils.StringUtils;
import com.huitone.smspfm.socket.utils.SerialUtils;
import com.huitone.smspfm.socket.client.SocketClient;
import com.huitone.smspfm.socket.core.ClientServerUserChecker;
import com.huitone.smspfm.socket.protocol.sgip.constant.Constant;
import com.huitone.smspfm.socket.protocol.sgip.message.msgbody.Submit;
import com.huitone.smspfm.socket.protocol.sgip.message.msghead.Head;
import com.huitone.smspfm.socket.server.SocketServer;



/**
* @Title ClientSample.java
* @Package com.api.test
* @Description 本例子主要展示客户端的使用方式
* @author ybliang
* @date 2017年4月25日 下午4:34:23
* @version V1.0
*/
public class SendSpeedTestClient {

	private volatile static long count = 0;
	private volatile static long countS = 0;
	private static Object myLock = new Object();
	public static void main(String[] args) throws IOException {
		if(! StringUtils.isEmpty(args) && args.length > 0){
			Config.init(args[0]);
		} else {
			Config.init(null);
		}

		// 业务端作为服务端↓

		/**
		 * 启动服务(此时为短信服务端) 用于接收短信报告, 上行短信
		 * 注意:
		 *    构造下发短信时传入reportFlag标记决定是否接收短信报告信息,reportFlag 有三个可选项: 0 该条消息只有最后出错时要返回状态报告; 1 该条消息无论最后是否成功都要返回状态报告; 2-该条消息不需要返回状态报告
		 */
		if(Config.IS_CREATE_SERVER){
			SocketServer.getInstance()
		    	.setMessageHandler(new ClientServerMessageHandler()) // 这个类的两个方法将用于接收短信报告信息及上行短信
		    	.setUserChecker(new ClientServerUserChecker(Config.CLIENT_USER_NAME, Config.CLIENT_PASSWORD)) // (新增)短信平台连接客户端的用户名密码(由短信平台分配)
		    	.setPort(Config.CLIENT_PORT) // 客户端作为服务端接收下行短信报告及上行短信时的端口号
		    	.setMaxActive(30) // 最大活动连接
		    	.setSoTimeOut(30000) // 连接空闲释放时间
		    	.start();
		}

		// 业务端是客户端↓

		// 需要为客户端设置配置参数
		
//		String pawd = new String(Base64.decodeBase64("MjI="));
		
		Date startDate = new Date();
		System.out.println("测试启动:"+startDate);

		SocketClient.getInstance().setMessageHandler(new ClientMessageHandler())
			.setServerIp(Config.SERVER_IP) // 短信平台的IP地址 (短信平台接口地址)
			.setServerPort(Config.SERVER_PORT) // 短信平台的端口号
			.setLoginName(Config.LOGIN_NAME)  // 用户名 (短信平台分配)
			.setLoginPassword(Config.LOGIN_PASSWORD) // 密码 (短信平台分配)
			.setSrvNode(Config.SVR_NODE) // 业务端编码 (短信平台分配)
			.setCoderule(Config.SERVICE_ID); // 业务端编号规则(短信平台分配)
		
		/*
		 * 该客户端功能和SocketClient一样，但是允许创建多个
		 * SmsClient client = new SmsClient();
		client.setSrvNode("100004");
		client.setServerIp("127.0.0.1");
		client.setServerPort(8901);
		client.setLoginName("test");
		client.setLoginPass("123456");
		client.setMessageHandler(new com.huitone.smspfm.socket.core.handler.DefaultMessageHandler());
		client.setMaxSize(1000);
		client.bind();*/	
		
		new Thread(new Runnable() {
			
			public void run() {
				while (true) {
					try {
						Thread.sleep(1000);
						if(Config.TEST_SPEED){
							System.out.println("短信发送的速率为: " + countS + " 条/秒");
						}
						if(Config.TEST_REPORT){
							if(Config.reportStratDate != null){
								System.out.println("短信报告接收速率为: " + Config.reportCntTmp);
							} else {
								System.out.println("短信报告未开始");
							}
						}
						synchronized (myLock) {
							count += countS;
							countS = 0;
							
							Config.reportCnt += Config.reportCntTmp;
							Config.reportCntTmp = 0;
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if(Config.TEST_SPEED){
					if (count >= Config.LOOP_TIMES) {
						break;
					}
					}
					if(Config.TEST_REPORT){
						if (Config.reportCnt >= Config.LOOP_TIMES) {
							long handlerTime = (new Date().getTime() - Config.reportStratDate.getTime());
							System.out.println("短信已成功发送:" +Config.LOOP_TIMES+"条,用时:" + handlerTime +" ms" );
							System.out.println("");
							break;
						}
					}
				}

			}
			}).start();
		

		int num = 0;
		
		while(true) {
			// 构造下发短信消息体
			String userNum = null;
			if(Config.IS_NUM_PREFIX){
				userNum = Config.NUM_PREFIX+String.format("%08d", ++num);
			}else{
				userNum = Config.NUM_PREFIX;
			}
			Submit submit = Submit.build(Collections.singletonList(userNum), //用户号码,最多一百个
					Config.SVR_NODE, // 业务端编码 (短信平台分配)
					Config.SERVICE_CODE, // 业务类型编码 (短信平台分配)
					Config.SEND_PORT, // 发送端口号 (短信平台分配)
					Config.REPORT_FLAG, // 有三个可选项: 0 该条消息只有最后出错时要返回状态报告; 1 该条消息无论最后是否成功都要返回状态报告; 2-该条消息不需要返回状态报告
					Constant.MessageCodingE.GBK.getValue(), // 默认
					Constant.MessageTypeE.SMS.getValue(), // 默认
					Config.SMS_CONTENT); // 短信内容
//					sb.toString()); // 短信内容
			//ActiveTest activeTest = new ActiveTest();
			// 构造下发短信消息头
			Head head = Head.build(submit.length(), // 短信消息体长度
					Config.SERVICE_ID,  // 业务端编号规则 (短信平台分配)
					StringUtils.tolong(DateTimeUtils.dateToStr(new Date(), "MMddHHmmss")), // 时间
					SerialUtils.getSerial()); // 序号从零到Integer.MAX_VALUE循环使用
			
			// 发送短信
			boolean sendFlag = SocketClient.getInstance().sendMsg(head, submit);
			if(sendFlag){
				countS ++;
			}
			if((count+countS) >= Config.LOOP_TIMES){
				break;
			}
			
			if (Config.SLEEP_MILLI > 0) {
				try {
					Thread.sleep(Config.SLEEP_MILLI);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		long handlerTime = (new Date().getTime() - startDate.getTime());
		System.out.println("短信已成功发送:" +Config.LOOP_TIMES+"条,用时:" + handlerTime +" ms" );
		
		if (Config.IS_CREATE_SERVER) {
			while (! Config.QUIT_FLAG && ! SocketServer.getInstance().isInterrupted()) {
				try {
					System.out.println("等待报告接收服务退出");
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			SocketServer.getInstance().shutdown();
			
		}
		SocketClient.getInstance().shutdown();
		System.out.println("短信测试服务已经退出");


	}
}
